<!Doctype html>
<html>
<head></head>
<body>
<div id="div">
    <p><span>11</span><span class="spans">222</span></p>
</div>
<script>
    (function (ns) {

        var doc = document;

        function api(query, context) {

            context = context || doc;

            //调用原生选择器
            if (!context.querySelectorAll) {
                return context.querySelectorAll(query);
            } else {
                //调用自定义选择器
                return interpret(query, context);
            }

        }

        //解释执行dom选择符
        function interpret(query, context) {
            var parts = query.replace(/\s+/, " ").split(" ");
            var part = parts.pop();
            var selector = Factory.create(part);
            var ret = selector.find(context);

            return (parts[0] && ret[0]) ? filter(parts, ret) : ret;
        }

        //ID选择器
        function IDSelector(id) {
            this.id = id.substring(1);
        }

        IDSelector.prototype = {

            find: function (context) {
                var ret = [];
                ret.push(context.getElementById(this.id));
                return ret;
            },

            match: function (element) {
                return element.id == this.id;
            }

        };
        IDSelector.test = function (selector) {

            var regex = /^#([\w\-_]+)/;

            return regex.test(selector);

        };

        //元素选择器
        function TagSelector(tagName) {
            this.tagName = tagName.toUpperCase();
        }

        TagSelector.prototype = {

            find: function (context) {
                return context.getElementsByTagName(this.tagName);

            },

            match: function (element) {
                return this.tagName == element.tagName.toUpperCase() || this.tagName === "*";
            }
        };
        TagSelector.test = function (selector) {
            var regex = /^([\w\*\-_]+)/;
            return regex.test(selector);
        };

        //类选择器
        function ClassSelector(className) {
            var splits = className.split('.');

            this.tagName = splits[0] || undefined;
            this.className = splits[1];
        }

        ClassSelector.prototype = {

            find: function (context) {
                var elements;
                var ret = [];
                var tagName = this.tagName;
                var className = this.className;
                var selector = new TagSelector((tagName || "*"));

                //支持原生getElementsByClassName
                if (context.getElementsByClassName) {
                    elements = context.getElementsByClassName(className);
                    if (!tagName) {
                        return elements;
                    }
                    for (var i = 0, n = elements.length; i < n; i++) {
                        if (selector.match(elements[i])) {
                            ret.push(elements[i]);
                        }
                    }

                } else {
                    elements = selector.find(context);
                    for (var i = 0, n = elements.length; i < n; i++) {
                        if (this.match(elements[i])) {
                            ret.push(elements[i]);
                        }
                    }
                }

                return ret;

            },

            match: function (element) {
                var className = this.className;
                var regex = new RegExp("^|\\s" + className + "$|\\s");
                return regex.test(element.className);
            }

        };
        ClassSelector.test = function (selector) {
            var regex = /^([\w\-_]*)\.([\w\-_]+)/;

            return regex.test(selector);
        };

        //根据父级元素过滤
        function filter(parts, nodeList) {
            var part = parts.pop();
            var selector = Factory.create(part);
            var ret = [];
            var parent;

            for (var i = 0, n = nodeList.length; i < n; i++) {
                parent = nodeList[i].parentNode;
                while (parent && parent !== doc) {
                    if (selector.match(parent)) {
                        ret.push(nodeList[i]);
                        break;
                    }
                    parent = parent.parentNode;
                }
            }

            return (parts[0] && ret[0]) ? filter(parts, ret) : ret;
        }

        //根据查询选择符创建相应选择器对象
        var Factory = {

            create: function (query) {

                if (IDSelector.test(query)) {
                    return new IDSelector(query);
                } else if (ClassSelector.test(query)) {
                    return new ClassSelector(query);
                } else {
                    return new TagSelector(query);
                }
            }
        };

        ns.dom || (ns.dom = {});
        ns.dom.get = api;
    }(this));

    //tagName
    console.log(dom.get("p")[0]);

    //#id
    console.log(dom.get("#div"));

    //.class
    console.log(dom.get(".spans", dom.get("p")[0]));

    //tag.class
    console.log(dom.get("span.spans"));

    //#id .class
    console.log(dom.get("#div .spans"));
    /*
     //.class .class
     console.log(dom.get(".ul .li-test"));
     */
</script>
</body>
</html>